import {
  _decorator,
  Collider2D,
  Contact2DType,
  ERigidBody2DType,
  EventTouch,
  IPhysics2DContact,
  Node,
  PhysicsSystem2D,
  PolygonCollider2D,
  RigidBody2D,
  tween,
  Tween,
  UITransform,
  v3,
  Vec2,
  Vec3,
} from 'cc';
import BaseUI from '../../common/base/BaseUI';
import { GameModel_Ins } from './GameModel';
import { autoComp, autoNode, rootNode } from '../../common/manager/BaseManager';
import { PoolFactory } from '../../common/component/PoolFactory';
import { Screenshot2DModel_Ins } from './Screenshot2DModel';
import { MathUtil } from '../../common/utils/MathUtils';
import { MultiPlatform, Platform } from '../../Platform/MultiPlatform';

const { ccclass, property } = _decorator;
@ccclass('GamePanel')
export default class GamePanel extends BaseUI {
  @autoComp(PoolFactory, rootNode)
  factory: PoolFactory;
  @autoComp(UITransform, rootNode)
  trans: UITransform;

  @autoNode()
  hand: Node;
  @autoNode()
  objNode: Node;
  @autoNode()
  shotNode: Node;

  // @autoNode()
  // bacon: Node;

  @autoNode()
  box: Node;
  @autoNode()
  guide: Node;

  contactArr: string[] = [];
  levelPass: boolean = false;
  settlementLock: boolean = true;
  protected onLoad(): void {}
  protected onEnable(): void {
    GameModel_Ins.panel = this;
    this.refreshUI();
    this.refreshLevel();
    // this.createObj();
    // this.createObj();
    // this.createObj();

    this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
    this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);

    // 注册单个碰撞体的回调函数
    // let collider = this.box.getComponent(Collider2D);
    // if (collider) {
    //   collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    //   collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
    // }
    // collider = this.ballon_collider.node.getComponent(Collider2D);
    // if (collider) {
    //   collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    //   collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
    // }

    // 注册全局碰撞回调函数
    if (PhysicsSystem2D.instance) {
      PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
      PhysicsSystem2D.instance.on(Contact2DType.END_CONTACT, this.onEndContact, this);
    }

    if (!window['timeEnd']) window['timeEnd'] = 25;
    if (MultiPlatform.Ins().platform === Platform.wx && window['timeEnd'] != undefined) {
      setTimeout(() => {
        this.onTouchEnd(null);
        MultiPlatform.Ins().platformUnit.notifyMiniProgramPlayableStatus();
      }, Number(window['timeEnd']) * 1000);
    }
  }

  refreshUI() {
    // this.shotNode.active = false;
    this.guide.active = false;
  }
  private guideAni: boolean = false;
  /** 刷新关卡 */
  refreshLevel() {
    this.levelPass = false;
    this.settlementLock = true;
    Tween.stopAllByTarget(this.objNode);
    this.objNode.setPosition(0, 0);
    const pos0 = new Vec3(750, 0);
    const pos1 = new Vec3(0, 0);
    tween(this.objNode)
      .to(0.5, { position: pos0 })
      .call(this.refreshSprite.bind(this))
      .to(0.5, { position: pos1 })

      .call(this.refreshObj.bind(this))
      .start();
    // this.refreshObj();
  }
  @autoNode()
  spriteParent: Node;

  spriteIndex: number = 0;
  private spriteTotalCount: number = 0;
  /** 刷新图片 */
  refreshSprite() {
    this.bacon = null;
    if (this.baconNode) {
      this.baconNode.removeFromParent();
      this.baconNode.destroy();
    }
    this.baconNode = null;
    while (this.spriteParent.children.length > 0) {
      this.factory.push(this.spriteParent.children[this.spriteParent.children.length - 1]);
    }
    const key = `level${this.spriteIndex + 1}`;
    let hasKey = false;
    const levelKey = [];
    this.factory.prefabs.forEach((p) => {
      if (p.name === key) hasKey = true;
      p.name.match('level') && p.name.match('level').length > 0 && levelKey.push(p.name);
    });
    if (hasKey) {
      const spr = this.factory.pop(key);
      this.spriteParent.addChild(spr);
    } else {
      const spr = this.factory.pop(levelKey[MathUtil.randomIntegerBetween(0, levelKey.length)]);
      this.spriteParent.addChild(spr);
    }
  }

  private baconNode: Node = null;
  private bacon: Node = null;
  private baconReady: boolean = false;
  /** 刷新培根 */
  refreshObj() {
    this.baconReady = true;
    this.contactArr.length = 0;
    Tween.stopAllByTarget(this.hand);
    this.hand.setPosition(-450, 240);
    tween(this.hand)
      .delay(0.1)
      .to(0.5, { position: v3(-150, 240) })

      .start();

    this.baconNode = this.factory.pop('baconNode');
    this.objNode.addChild(this.baconNode);
    this.baconNode.setPosition(0, 0);

    this.bacon = this.baconNode.children[0];
    Tween.stopAllByTarget(this.bacon);
    // this.bacon.setPosition(-450, 200);
    this.baconNode.children.forEach((child, i) => {
      child.setPosition(-450, 200 - i * 15);
    });
    this.baconNode.children.forEach((child, i) => {
      child.getComponent(RigidBody2D).type = i != 0 ? ERigidBody2DType.Dynamic : ERigidBody2DType.Kinematic;
    });
    tween(this.bacon)
      .delay(0.1)
      .to(0.5, { position: v3(-150, 200) })
      .call(() => {
        this.baconReady = true;
        if (this.guideAni) return;
        this.guide.active = true;
        this.guideAni = true;
      })
      .start();

    this.spriteParent.children.forEach((child, i) => {
      child.getComponent(PolygonCollider2D).apply();
    });
  }
  private moveEnable: boolean = false;
  private moveSpeed: number = 100;
  private lastSpace: number = -1;
  protected update(dt: number): void {
    if (this.levelPass) return;
    // this.ballon_collider.node.translate(Vec3.ZERO, NodeSpace.LOCAL);
    // this.updateMapPos();
    // if (this.moveEnable) {
    //   const moveSpace = new Vec3(0, 1, 0);
    //   moveSpace.y = dt * this.moveSpeed;
    //   this.Camera.translate(moveSpace, NodeSpace.LOCAL);
    // }
    // const nextObjY = 200 + this.objIndex * 400;
    // if (nextObjY - this.Camera.getPosition().y <= 750) {
    //   this.createObj();
    // }
    const angleSpace = (this.targetAngle - this.box.angle) * dt * 8;
    if (this.contactArr.length > 0 && angleSpace > 0) {
      // 计算冲力大小
      // const force = Math.abs(angleSpace) * 10;
      // 计算冲力方向
      // const dir = new Vec2(Math.cos(this.box.angle), Math.sin(this.box.angle));
      // const dir = new Vec2(0, 1);
      // 应用冲力
      // this.bacon.getComponent(RigidBody2D).applyLinearImpulse(dir.multiplyScalar(5), new Vec2(), true);
      const scale = (2 * Math.abs(angleSpace)) / 40;
      console.log(angleSpace, scale);
      this.baconNode.children.forEach((child, i) => {
        // if (this.contactArr.indexOf(child.uuid) == -1) return;
        // child.getComponent(RigidBody2D).type = i != 0 ? ERigidBody2DType.Dynamic : ERigidBody2DType.Kinematic;
        // const dir = new Vec2(Math.cos(((child.angle + 90) * Math.PI) / 180), Math.sin(((child.angle + 90) * Math.PI) / 180));
        const dir = new Vec2(0, 1);
        console.log(dir);
        child.getComponent(RigidBody2D).applyLinearImpulse(dir.multiplyScalar(scale), new Vec2(), true);
      });
    }
    this.lastSpace = angleSpace;
    this.box.angle += angleSpace;

    if (this.bacon && (this.bacon.getPosition().y < -1338 / 2 || this.bacon.getPosition().x < -750 / 1.5 || this.bacon.getPosition().x > 750 / 1.5)) {
      // 检测位置
      this.bacon = null;
      this.baconNode.removeFromParent();
      this.baconNode.destroy();
      this.baconNode = null;
      this.refreshObj();
    }

    this.checkWin();
  }
  private targetAngle: number = -20;
  onTouchStart(t: EventTouch) {
    this.targetAngle = 30;
    if (this.baconReady && this.bacon && this.bacon.getComponent(RigidBody2D).type === ERigidBody2DType.Kinematic) {
      this.bacon.getComponent(RigidBody2D).type = ERigidBody2DType.Dynamic;
      this.hand.setPosition(-450, 240);
      this.baconReady = false;
      this.guide.active = false;
      // this.settlement();
      setTimeout(() => {
        this.settlementLock = false;
      }, 1000);
    }
  }

  onTouchEnd(t: EventTouch) {
    this.targetAngle = -20;
  }

  /** 检测胜利 */
  checkWin() {
    if (this.settlementLock || !this.baconNode) return;
    let count = 0;
    const minChick = 0.01;
    this.baconNode.children.forEach((child, i) => {
      const rigid = child.getComponent(RigidBody2D);
      if (rigid.type === ERigidBody2DType.Dynamic && Math.abs(rigid.linearVelocity.x) <= minChick && Math.abs(rigid.linearVelocity.y) <= minChick) count++;
    });
    if (count >= this.baconNode.children.length) this.settlement();
  }

  /** 结算 */
  settlement() {
    this.levelPass = true;
    this.baconNode.children.forEach((child, i) => {
      const rigid = child.getComponent(RigidBody2D);
      rigid.type = ERigidBody2DType.Static;
    });
    this.spriteIndex++;
    this.refreshLevel();
    // Screenshot2DModel_Ins.panel.capture();
    // this.shotNode.active = true;
  }

  // private objIndex: number = 0;
  // /** 创建障碍物 */
  // createObj() {
  //   const nameArr = [];
  //   this.factory.prefabs.forEach((p) => nameArr.push(p.name));
  //   const obj = this.factory.pop(nameArr[MathUtil.randomIntegerBetween(0, nameArr.length)]);
  //   this.objNode.addChild(obj);
  //   obj.setPosition(0, 200 + this.objIndex * 400);
  //   this.objIndex++;
  // }

  // private mapIndex: number = 0;
  // /** 更新地图位置 */
  // updateMapPos() {
  //   // this.mapIndex = Math.round(this.Camera.getPosition().y / 750);
  //   // this.mapNode.children.forEach((child, i) => {
  //   //   child.setPosition(0, -750 + (i + this.mapIndex) * 750);
  //   // });
  //   // const cameraPosY = this.Camera.getPosition().y;
  //   // const removeChild: Node[] = [];
  //   // this.objNode.children.forEach((child, i) => {
  //   //   if (cameraPosY - child.getPosition().y >= 750) removeChild.push();
  //   // });
  //   // while (removeChild.length > 0) {
  //   //   const item = removeChild.shift();
  //   //   item.removeFromParent();
  //   //   item.destroy();
  //   //   // this.factory.push();
  //   // }
  // }

  // private press: boolean = false;
  // private pressPoint: Vec3 = null;
  // onTouchStart(t: EventTouch) {
  //   if (this.press) return;
  //   this.press = true;
  //   const uiPos = t.getUILocation();
  //   this.pressPoint = new Vec3(uiPos.x, uiPos.y);
  //   this.trans.convertToNodeSpaceAR(this.pressPoint, this.pressPoint);
  //   this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
  //   this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
  //   this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
  // }
  // onTouchMove(t: EventTouch) {
  //   if (!this.press) return;
  //   const uiNewPos = t.getUILocation();
  //   const newPos = new Vec3(uiNewPos.x, uiNewPos.y);
  //   const movePos = this.trans.convertToNodeSpaceAR(newPos);
  //   this.bacon.translate(new Vec3(movePos.x - this.pressPoint.x, movePos.y - this.pressPoint.y, 0), NodeSpace.LOCAL);
  //   this.pressPoint = movePos;
  //   this.moveEnable = true;
  // }
  // onTouchEnd(t: EventTouch) {
  //   if (!this.press) return;
  //   this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
  //   this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
  //   this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
  //   this.press = false;
  // }
  onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
    // 只在两个碰撞体开始接触时被调用一次
    // console.log('onBeginContact', selfCollider.node.name, otherCollider.node.name);
    // switch (selfCollider.node.name) {
    //   case 'ballon_collider':
    //     switch (otherCollider.node.name) {
    //       case 'barrier_box':
    //       case 'barrier_circle':
    //         this.showSettlement(false);
    //         break;
    //     }
    //     break;
    //   case 'touchBox':
    //     switch (otherCollider.node.name) {
    //       case 'barrier_box':
    //         if (otherCollider.body.type === ERigidBody2DType.Kinematic) {
    //           otherCollider.node.parent.children.forEach((child) => {
    //             const rigid = child.getComponent(RigidBody2D);
    //             rigid.type = ERigidBody2DType.Dynamic;
    //             rigid.wakeUp();
    //           });
    //         }
    //         break;
    //       case 'barrier_circle':
    //         {
    //           const pos1 = selfCollider.node.getPosition().clone();
    //           const pos2 = otherCollider.node.getWorldPosition().clone();
    //           this.trans.convertToNodeSpaceAR(pos2, pos2);
    //           let dir = new Vec2(pos2.x - pos1.x, pos2.y - pos1.y);
    //           dir = dir.normalize();
    //           dir = dir.multiplyScalar(1);
    //           otherCollider.body.applyLinearImpulse(dir, new Vec2(), true);
    //         }
    //         break;
    //     }
    //     break;
    // }

    if (selfCollider.node.name === 'box') {
      console.log('onBeginContact', selfCollider.node.name, otherCollider.node.name);
      if (otherCollider.node.name.match('bacon').length > 0 && this.contactArr.indexOf(otherCollider.node.uuid) === -1) {
        this.contactArr.push(otherCollider.node.uuid);
      }
    }
  }
  onEndContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
    // 只在两个碰撞体结束接触时被调用一次
    if (selfCollider.node.name === 'box') {
      console.log('onEndContact', selfCollider.node.name, otherCollider.node.name);
      if (otherCollider.node.name.match('bacon').length > 0 && this.contactArr.indexOf(otherCollider.node.uuid) != -1) {
        this.contactArr.splice(this.contactArr.indexOf(otherCollider.node.uuid), 1);
      }
    }
  }
}
